package com.rizzo.infrastructure.redis.timeseries;

import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.format.ISOPeriodFormat;


public class TimeStep {

	public static final int DATA_POINT_LENGTH = 19;
	public static final int DATA_POINT_SPLIT_LENGTH = 13;

	public static String encodeTimeStep(DateTime time, Period timeStep) {
		DateTime dateTimeFloor = dateTimeFloor(time, timeStep);
		long timeStepKey = time.getMillis() - (time.getMillis() % dateTimeFloor.getMillis());
		return String.valueOf(timeStepKey);
	}

	public static DateTime dateTimeFloor(DateTime dateTime, Period period) {
		if (period.getYears() != 0) {
			return dateTime.yearOfEra().roundFloorCopy().minusYears(dateTime.getYearOfEra() % period.getYears());
		} else if (period.getMonths() != 0) {
			return dateTime.monthOfYear().roundFloorCopy().minusMonths((dateTime.getMonthOfYear() - 1) % period.getMonths());
		} else if (period.getWeeks() != 0) {
			return dateTime.weekOfWeekyear().roundFloorCopy().minusWeeks((dateTime.getWeekOfWeekyear() - 1) % period.getWeeks());
		} else if (period.getDays() != 0) {
			return dateTime.dayOfMonth().roundFloorCopy().minusDays((dateTime.getDayOfMonth() - 1) % period.getDays());
		} else if (period.getHours() != 0) {
			return dateTime.hourOfDay().roundFloorCopy().minusHours(dateTime.getHourOfDay() % period.getHours());
		} else if (period.getMinutes() != 0) {
			return dateTime.minuteOfHour().roundFloorCopy().minusMinutes(dateTime.getMinuteOfHour() % period.getMinutes());
		} else if (period.getSeconds() != 0) {
			return dateTime.secondOfMinute().roundFloorCopy().minusSeconds(dateTime.getSecondOfMinute() % period.getSeconds());
		}
		return dateTime.millisOfSecond().roundCeilingCopy().minusMillis(dateTime.getMillisOfSecond() % period.getMillis());
	}

	public static Period parsePeriod(String standardISOPeriod) {
		return Period.parse(standardISOPeriod);
	}

	public static String getStandardISOPeriod(Period period) {
		return period.toString(ISOPeriodFormat.standard());
	}

}
